package org.web.clientlistmanager.server.biz;

import io.netty.channel.ChannelHandlerContext;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.web.base.domain.ResultDO;
import org.web.base.domain.exception.ResultMessageEnum;
import org.web.base.domain.helper.ServiceExceptionHelper;
import org.web.clientlistmanager.sdk.dto.*;
import org.web.clientlistmanager.sdk.event.EventEnum;
import org.web.clientlistmanager.sdk.event.EventHelper;
import org.web.clientlistmanager.sdk.event.EventInterface;

import javax.annotation.Resource;
import java.lang.reflect.Field;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Service("clmReportSelfEvent")
public class ClmReportSelfEvent implements EventInterface {

    private static final Logger logger = Logger.getLogger(ClmReportSelfEvent.class);

    @Resource
    private ClmClientProcessBizImpl clmClientProcessBizImpl;


    /****
     * Key 是channel的id，value是uuid
     */
    public Map<String, String> getChannelMap() {
        return channelMap;
    }

    // 使用Map来保存连接信息，key为连接的标识，value表示客户端标识，即processMark信息。
    private final Map<String, String> channelMap = new ConcurrentHashMap<>();

    @Override
    public void executeRequest(ClmRequest clmRequest, ChannelHandlerContext ctx) {
        try {
            if (clmRequest != null && clmRequest.getContent() != null && StringUtils.isNotBlank(clmRequest.getContent().toString())) {

                LocalClientProcessDTO localClientProcessDTO;
                if (clmRequest.getContent() instanceof Map) {
                    localClientProcessDTO = fromMap((Map<String, Object>) clmRequest.getContent());
                } else if (clmRequest.getContent() instanceof LocalClientProcessDTO) {
                    localClientProcessDTO = (LocalClientProcessDTO) clmRequest.getContent();
                } else {
                    throw ServiceExceptionHelper.buildServiceException(ResultMessageEnum.PARAM_INVALID, clmRequest.toString());
                }


                ResultDO<String> saveLocalClientProcessRresultDO = clmClientProcessBizImpl.saveLocalClientProcessDTO(localClientProcessDTO);
                ClmRequest<ResultDTO> response = new ClmRequest<>();
                ResultDTO resultDTO = new ResultDTO();
                response.setContent(resultDTO);
                response.setEventName(EventEnum.clmReportSelfAckEvent.name());
                if (saveLocalClientProcessRresultDO.isSuccess()) {
                    resultDTO.setSuccess(true);
                    resultDTO.setResult(saveLocalClientProcessRresultDO.getDomain());
                    getChannelMap().put(ctx.channel().id().asLongText(), localClientProcessDTO.getProcessUuid());
                } else {
                    resultDTO.setSuccess(false);
                    resultDTO.setResult(ClmHelper.truncateString(saveLocalClientProcessRresultDO.getMessage(),200));
                }
                EventHelper.sendClmRequest(ctx, response);

            }
        } catch (Exception e) {
            logger.error(ServiceExceptionHelper.getExceptionInfo(e));
        }
    }

    private LocalClientProcessDTO fromMap(Map<String, Object> map) throws Exception {
        LocalClientProcessDTO insert = new LocalClientProcessDTO();
        for (Map.Entry<String, Object> entry : map.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();

            Field field = LocalClientProcessDTO.class.getDeclaredField(key);
            field.setAccessible(true);
            field.set(insert, value);
        }
        return insert;
    }

}
